const axios = require('axios');
const { OpenAI } = require('openai');
const Package = require('../models/Package');
const DownloadStat = require('../models/DownloadStat');
const Tag = require('../models/Tag');
const PackageTag = require('../models/PackageTag');
const { Op } = require('sequelize');
const fs = require('fs');
const path = require('path');
const syncStatusManager = require('./SyncStatusManager');

class SyncService {
  constructor() {
    // 直接从.env文件读取配置
    const envConfig = this.loadEnvConfig();

    // 验证必要的配置
    if (!envConfig.OPENAI_API_KEY) {
      throw new Error('OPENAI_API_KEY 未在.env文件中配置');
    }
    if (!envConfig.OPENAI_API_BASE_URL) {
      throw new Error('OPENAI_API_BASE_URL 未在.env文件中配置');
    }

    // 初始化OpenAI客户端，使用从.env文件直接读取的配置
    this.openai = new OpenAI({
      apiKey: envConfig.OPENAI_API_KEY,
      baseURL: envConfig.OPENAI_API_BASE_URL,
      defaultQuery: {
        api_key: envConfig.OPENAI_API_KEY,
      },
      defaultHeaders: {
        'Content-Type': 'application/json',
      },
    });

    console.log('OpenAI客户端初始化成功，使用.env文件配置:');
    console.log('- API Base URL:', envConfig.OPENAI_API_BASE_URL);
    console.log('- API Key:', envConfig.OPENAI_API_KEY ? `${envConfig.OPENAI_API_KEY.substring(0, 10)}...` : '未配置');
  }

  // 直接从.env文件读取配置
  loadEnvConfig() {
    try {
      const envPath = path.resolve(process.cwd(), '.env');
      const envContent = fs.readFileSync(envPath, 'utf8');
      const config = {};

      // 解析.env文件内容
      envContent.split('\n').forEach(line => {
        line = line.trim();
        if (line && !line.startsWith('#')) {
          const [key, ...valueParts] = line.split('=');
          if (key && valueParts.length > 0) {
            config[key.trim()] = valueParts.join('=').trim();
          }
        }
      });

      return config;
    } catch (error) {
      console.error('读取.env文件失败:', error);
      throw new Error('无法读取.env文件');
    }
  }

  // 带状态更新的批量同步方法
  async syncMultiplePackagesWithStatus(packageNames) {
    const results = [];
    const errors = [];
    const batchSize = 3; // 限制并发数量

    console.log(`开始同步 ${packageNames.length} 个包，批量大小: ${batchSize}`);

    // 分批处理，避免过多并发
    for (let i = 0; i < packageNames.length; i += batchSize) {
      const batch = packageNames.slice(i, i + batchSize);
      console.log(
        `处理批次 ${Math.floor(i / batchSize) + 1}/${Math.ceil(packageNames.length / batchSize)}: ${batch.join(', ')}`
      );

      const batchPromises = batch.map(async packageName => {
        try {
          const result = await this.syncPackageWithTimeout(packageName, 30000); // 30秒超时
          console.log(`✓ 同步成功: ${packageName}`);

          // 更新状态
          syncStatusManager.updateProgress(packageName, true);

          return {
            packageName,
            success: true,
            data: result,
          };
        } catch (error) {
          console.error(`✗ 同步失败: ${packageName}`, error.message);

          // 更新状态
          syncStatusManager.updateProgress(packageName, false, error);

          return {
            packageName,
            success: false,
            error: error.message || '同步失败',
          };
        }
      });

      const batchResults = await Promise.all(batchPromises);

      batchResults.forEach(result => {
        if (result.success) {
          results.push(result);
        } else {
          errors.push(result);
        }
      });

      // 批次间稍作延迟，避免API限流
      if (i + batchSize < packageNames.length) {
        await new Promise(resolve => setTimeout(resolve, 1000));
      }
    }

    console.log(`同步完成: 成功 ${results.length}，失败 ${errors.length}`);

    return {
      total: packageNames.length,
      succeeded: results.length,
      failed: errors.length,
      results,
      errors,
    };
  }

  // 批量同步多个包
  async syncMultiplePackages(packageNames) {
    const results = [];
    const errors = [];
    const batchSize = 3; // 限制并发数量

    console.log(`开始同步 ${packageNames.length} 个包，批量大小: ${batchSize}`);

    // 分批处理，避免过多并发
    for (let i = 0; i < packageNames.length; i += batchSize) {
      const batch = packageNames.slice(i, i + batchSize);
      console.log(
        `处理批次 ${Math.floor(i / batchSize) + 1}/${Math.ceil(packageNames.length / batchSize)}: ${batch.join(', ')}`
      );

      const batchPromises = batch.map(async packageName => {
        try {
          const result = await this.syncPackageWithTimeout(packageName, 30000); // 30秒超时
          console.log(`✓ 同步成功: ${packageName}`);
          return {
            packageName,
            success: true,
            data: result,
          };
        } catch (error) {
          console.error(`✗ 同步失败: ${packageName}`, error.message);
          return {
            packageName,
            success: false,
            error: error.message || '同步失败',
          };
        }
      });

      const batchResults = await Promise.all(batchPromises);

      batchResults.forEach(result => {
        if (result.success) {
          results.push(result);
        } else {
          errors.push(result);
        }
      });

      // 批次间稍作延迟，避免API限流
      if (i + batchSize < packageNames.length) {
        await new Promise(resolve => setTimeout(resolve, 1000));
      }
    }

    console.log(`同步完成: 成功 ${results.length}，失败 ${errors.length}`);

    return {
      total: packageNames.length,
      succeeded: results.length,
      failed: errors.length,
      results,
      errors,
    };
  }

  // 带超时的同步包方法
  async syncPackageWithTimeout(packageName, timeout = 30000) {
    return new Promise(async (resolve, reject) => {
      const timer = setTimeout(() => {
        reject(new Error(`同步超时: ${packageName}`));
      }, timeout);

      try {
        const result = await this.syncPackage(packageName);
        clearTimeout(timer);
        resolve(result);
      } catch (error) {
        clearTimeout(timer);
        reject(error);
      }
    });
  }

  // 同步单个包
  async syncPackage(packageName) {
    try {
      // 从npm获取包信息
      const npmData = await this.fetchPackageFromNPM(packageName);
      if (!npmData) {
        throw new Error(`无法获取包信息: ${packageName}`);
      }

      // 获取下载统计
      const downloadStats = await this.fetchDownloadStats(packageName);

      // 提取需要的信息
      const latestVersion = (npmData['dist-tags'] && npmData['dist-tags'].latest) || '';
      const description = npmData.description || '';
      const homepage = npmData.homepage || '';
      const repository =
        typeof npmData.repository === 'object' ? npmData.repository.url || '' : npmData.repository || '';
      const author = typeof npmData.author === 'object' ? npmData.author.name || '' : npmData.author || '';
      const license = npmData.license || '';
      const keywords = Array.isArray(npmData.keywords) ? npmData.keywords : [];

      console.log(`  📝 正在翻译描述: ${packageName}`);
      // 翻译描述
      const descriptionCN = await this.translateDescription(description);

      console.log(`  🏷️  正在生成标签: ${packageName}`);
      // 生成标签
      const suggestedTags = await this.generateTags(description, packageName);

      console.log(`  💾 正在保存包信息: ${packageName}`);
      // 保存或更新包信息到数据库
      let packageRecord = await Package.findOne({
        where: {
          name: packageName,
        },
      });

      if (packageRecord) {
        // 更新现有记录
        await packageRecord.update({
          latestVersion,
          description,
          descriptionCN,
          homepage,
          repository,
          author,
          license,
          lastSyncAt: new Date(),
        });
      } else {
        // 创建新记录
        packageRecord = await Package.create({
          name: packageName,
          latestVersion,
          description,
          descriptionCN,
          homepage,
          repository,
          author,
          license,
          lastSyncAt: new Date(),
        });
      }

      // 保存下载统计
      if (downloadStats && downloadStats.downloads) {
        const today = new Date().toISOString().split('T')[0]; // 只取日期部分

        try {
          // 使用upsert避免重复插入
          await DownloadStat.upsert({
            package_id: packageRecord.id,
            date: today,
            downloads: downloadStats.downloads,
          });
        } catch (error) {
          console.warn(`保存下载统计失败 (${packageName}):`, error.message);
          // 如果upsert失败，尝试更新现有记录
          try {
            await DownloadStat.update(
              {
                downloads: downloadStats.downloads,
              },
              {
                where: {
                  package_id: packageRecord.id,
                  date: today,
                },
              }
            );
          } catch (updateError) {
            console.warn(`更新下载统计也失败 (${packageName}):`, updateError.message);
          }
        }
      }

      // 处理标签
      if (suggestedTags && suggestedTags.length > 0) {
        for (const tagName of suggestedTags) {
          // 查找或创建标签
          const [tag] = await Tag.findOrCreate({
            where: {
              name: tagName,
            },
            defaults: {
              name: tagName,
            },
          });

          // 关联包和标签
          await PackageTag.findOrCreate({
            where: {
              package_id: packageRecord.id,
              tag_id: tag.id,
            },
          });
        }
      }

      // 处理关键词作为标签
      if (keywords && keywords.length > 0) {
        for (const keyword of keywords) {
          if (!keyword || typeof keyword !== 'string') continue;

          // 查找或创建标签
          const [tag] = await Tag.findOrCreate({
            where: {
              name: keyword,
            },
            defaults: {
              name: keyword,
            },
          });

          // 关联包和标签
          await PackageTag.findOrCreate({
            where: {
              package_id: packageRecord.id,
              tag_id: tag.id,
            },
          });
        }
      }

      return {
        id: packageRecord.id,
        name: packageRecord.name,
        version: packageRecord.latestVersion,
        description: packageRecord.description,
        descriptionCN: packageRecord.descriptionCN,
        downloads: (downloadStats && downloadStats.downloads) || 0,
        tags: suggestedTags,
      };
    } catch (error) {
      console.error(`同步包失败: ${packageName}`, error);
      throw error;
    }
  }

  // 从npm API获取包信息
  async fetchPackageFromNPM(packageName) {
    try {
      const response = await axios.get(`https://registry.npmjs.org/${packageName}`, {
        timeout: 10000, // 10秒超时
        headers: {
          'User-Agent': 'npm-explore/1.0.0',
        },
      });
      return response.data;
    } catch (error) {
      console.warn(`获取npm包信息失败: ${packageName}`, error.message);
      return null;
    }
  }

  // 从npm API获取下载统计
  async fetchDownloadStats(packageName) {
    try {
      const response = await axios.get(`https://api.npmjs.org/downloads/point/last-month/${packageName}`, {
        timeout: 10000, // 10秒超时
        headers: {
          'User-Agent': 'npm-explore/1.0.0',
        },
      });
      return response.data;
    } catch (error) {
      console.warn(`获取下载统计失败: ${packageName}`, error.message);
      return null;
    }
  }

  // 使用OpenAI翻译描述
  async translateDescription(description) {
    try {
      if (!description || description.length === 0) {
        return '';
      }

      // 限制描述长度，避免API调用过长
      const truncatedDescription = description.length > 500 ? description.substring(0, 500) + '...' : description;

      const response = await Promise.race([
        this.openai.chat.completions.create({
          model: 'qwen-plus',
          messages: [
            {
              role: 'system',
              content: '你是一个专业的翻译助手，请将英文技术文档翻译成中文，保持技术准确性和专业性。',
            },
            {
              role: 'user',
              content: `请翻译以下npm包描述为中文：${truncatedDescription}`,
            },
          ],
          max_tokens: 500,
          timeout: 10000, // 10秒超时
        }),
        new Promise((_, reject) => setTimeout(() => reject(new Error('翻译请求超时')), 15000)),
      ]);

      return (response.choices[0] && response.choices[0].message && response.choices[0].message.content) || description;
    } catch (error) {
      console.warn('翻译失败，使用原文:', error.message);
      return description; // 如果翻译失败，返回原文
    }
  }

  // 使用OpenAI生成标签
  async generateTags(description, name) {
    try {
      // 简化输入，避免过长的描述
      const shortDescription = description.length > 200 ? description.substring(0, 200) + '...' : description;

      const response = await Promise.race([
        this.openai.chat.completions.create({
          model: 'qwen-plus',
          messages: [
            {
              role: 'system',
              content:
                '你是一个npm包分类专家，请根据包的名称和描述，为其生成3-5个中文标签，用逗号分隔。标签应该简洁明了。',
            },
            {
              role: 'user',
              content: `包名称：${name}\n包描述：${shortDescription}\n请生成3-5个中文标签，用逗号分隔：`,
            },
          ],
          max_tokens: 100,
          timeout: 10000, // 10秒超时
        }),
        new Promise((_, reject) => setTimeout(() => reject(new Error('标签生成请求超时')), 15000)),
      ]);

      const tagsText =
        (response.choices[0] && response.choices[0].message && response.choices[0].message.content) || '';
      // 解析标签并去重
      const tags = [
        ...new Set(
          tagsText
            .split(',')
            .map(tag => tag.trim())
            .filter(tag => tag.length > 0)
        ),
      ];
      return tags.slice(0, 5); // 最多保留5个标签
    } catch (error) {
      console.warn('生成标签失败，使用默认标签:', error.message);
      // 返回基于包名的简单标签
      return this.generateSimpleTags(name);
    }
  }

  // 生成简单标签（当AI失败时的备选方案）
  generateSimpleTags(packageName) {
    const commonTags = {
      react: ['前端框架', 'UI库'],
      vue: ['前端框架', 'UI库'],
      angular: ['前端框架', 'UI库'],
      express: ['后端框架', 'Web服务'],
      koa: ['后端框架', 'Web服务'],
      lodash: ['工具库', '实用函数'],
      axios: ['网络请求', 'HTTP客户端'],
      moment: ['日期处理', '时间工具'],
      jquery: ['DOM操作', 'UI库'],
      webpack: ['构建工具', '打包工具'],
      babel: ['编译工具', '转换器'],
      eslint: ['代码检查', '开发工具'],
      jest: ['测试框架', '单元测试'],
      mocha: ['测试框架', '单元测试'],
    };

    // 检查包名中是否包含已知关键词
    for (const [keyword, tags] of Object.entries(commonTags)) {
      if (packageName.toLowerCase().includes(keyword)) {
        return tags;
      }
    }

    // 默认标签
    return ['工具库'];
  }

  // 批量同步包
  async syncPackages(packageNames, maxConcurrent = 3) {
    try {
      if (!Array.isArray(packageNames) || packageNames.length === 0) {
        throw new Error('请提供要同步的包列表');
      }

      const results = [];

      // 分批处理
      for (let i = 0; i < packageNames.length; i += maxConcurrent) {
        const batch = packageNames.slice(i, i + maxConcurrent);
        const batchResults = await Promise.all(
          batch.map(async packageName => {
            try {
              // 调用同步单个包的逻辑
              await this.syncPackage(packageName);
              return {
                name: packageName,
                success: true,
              };
            } catch (error) {
              console.error(`同步包失败: ${packageName}`, error);
              return {
                name: packageName,
                success: false,
                error: error.message,
              };
            }
          })
        );
        results.push(...batchResults);
      }

      return results;
    } catch (error) {
      console.error('批量同步失败:', error);
      throw error;
    }
  }

  // 同步热门包
  async syncTrendingPackages() {
    const syncId = syncStatusManager.startSync('trending');

    try {
      // 热门npm包列表（实际项目中应该从npm API获取）
      const trendingPackages = [
        'react',
        'vue',
        'angular',
        'express',
        'koa',
        'fastify',
        'lodash',
        'underscore',
        'ramda',
        'axios',
        'fetch',
        'request',
        'moment',
        'dayjs',
        'date-fns',
        'jquery',
        'zepto',
        'webpack',
        'rollup',
        'parcel',
        'babel',
        'typescript',
        'eslint',
        'prettier',
        'jest',
        'mocha',
        'chai',
      ];

      console.log(`开始同步 ${trendingPackages.length} 个热门包`);

      // 更新总包数
      if (syncStatusManager.currentSync) {
        syncStatusManager.currentSync.totalPackages = trendingPackages.length;
      }

      const results = await this.syncMultiplePackagesWithStatus(trendingPackages);

      syncStatusManager.completeSync(true);
      return results;
    } catch (error) {
      console.error('同步热门包失败:', error);
      syncStatusManager.completeSync(false);
      throw error;
    }
  }

  // 获取同步状态
  async getSyncStatus() {
    try {
      return syncStatusManager.getCurrentStatus();
    } catch (error) {
      console.error('获取同步状态失败:', error);
      throw new Error('获取同步状态失败');
    }
  }

  // 获取同步配置
  async getSyncConfig() {
    try {
      // 返回默认配置，实际应该从数据库读取
      return {
        sourceUrl: 'https://registry.npmjs.org/',
        timeoutSeconds: 300,
        batchSize: 50,
        autoSync: false,
        syncFrequency: 'daily',
      };
    } catch (error) {
      console.error('获取同步配置失败:', error);
      throw new Error('获取同步配置失败');
    }
  }

  // 更新同步配置
  async updateSyncConfig(config) {
    try {
      // 这里应该将配置保存到数据库
      // 简化实现，直接返回配置
      return config;
    } catch (error) {
      console.error('更新同步配置失败:', error);
      throw new Error('更新同步配置失败');
    }
  }

  // 取消同步
  async cancelSync() {
    try {
      const cancelled = syncStatusManager.cancelSync();
      return {
        success: cancelled,
        message: cancelled ? '同步已取消' : '没有正在进行的同步任务',
      };
    } catch (error) {
      console.error('取消同步失败:', error);
      throw new Error('取消同步失败');
    }
  }

  // 获取同步历史
  async getSyncHistory({ status, page = 1, pageSize = 10, startDate, endDate }) {
    try {
      const history = syncStatusManager.getHistory(50); // 获取最近50条记录

      // 根据状态筛选
      let filteredItems = history.items;
      if (status) {
        filteredItems = filteredItems.filter(item => item.status === status);
      }

      // 分页
      const total = filteredItems.length;
      const start = (page - 1) * pageSize;
      const items = filteredItems.slice(start, start + pageSize);

      return {
        items,
        total,
        pages: Math.ceil(total / pageSize),
        currentPage: page,
      };
    } catch (error) {
      console.error('获取同步历史失败:', error);
      throw new Error('获取同步历史失败');
    }
  }

  // 获取同步历史详情
  async getSyncHistoryDetail(id) {
    try {
      const detail = syncStatusManager.getHistoryDetail(id);
      if (!detail) {
        throw new Error('同步记录不存在');
      }
      return detail;
    } catch (error) {
      console.error('获取同步历史详情失败:', error);
      throw new Error('获取同步历史详情失败');
    }
  }

  // 清空同步历史
  async clearSyncHistory() {
    try {
      syncStatusManager.clearHistory();
      return {
        success: true,
        message: '同步历史已清空',
      };
    } catch (error) {
      console.error('清空同步历史失败:', error);
      throw new Error('清空同步历史失败');
    }
  }

  // 标记热门包
  async markPopularPackages(topN = 100) {
    try {
      // 首先将所有包标记为非热门
      await Package.update(
        {
          is_popular: false,
        },
        {
          where: {},
        }
      );

      // 查找下载量最高的前N个包
      const popularPackages = await Package.findAll({
        order: [['downloads', 'desc']],
        limit: topN,
        attributes: ['id'],
      });

      // 将这些包标记为热门
      const packageIds = popularPackages.map(pkg => pkg.id);
      await Package.update(
        {
          is_popular: true,
        },
        {
          where: {
            id: {
              [Op.in]: packageIds,
            },
          },
        }
      );

      return {
        marked: packageIds.length,
      };
    } catch (error) {
      console.error('标记热门包失败:', error);
      throw new Error('标记热门包失败');
    }
  }
}

module.exports = new SyncService();
